package com.zmn.oms.zmn.business.impl.ins;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.oms.common.constant.InsConsts;
import com.zmn.oms.model.entity.ins.*;
import com.zmn.oms.services.interfaces.ins.*;
import com.zmn.oms.zmn.business.interfaces.ins.InsOrderBService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 类描述：
 *
 * @author lhl
 * @date 2020/06/02 17:57
 */
@Slf4j
@Service("insOrderBService")
public class InsOrderBServiceImpl implements InsOrderBService {

    private static final String REG_CARDNO = "^\\d{17}[0-9|x|X]$";

    //保险单状态: 0开始，1结束
    private static final int INS_SYNC_STATUS_START = 0;
    private static final int INS_SYNC_STATUS_END = 1;

    @Autowired
    private InsOrderService insOrderService;
    @Autowired
    private InsOrderMasterService insOrderMasterService;
    @Autowired
    private InsOrderSyncService insOrderSyncService;
    @Autowired
    private InsOrderMasterSyncService insOrderMasterSyncService;
    @Autowired
    private InsOrderMasterCpicService insOrderMasterCpicService;

    @Override
    public InsOrder findInsOrderByOrderId(Long orderId) {
        return insOrderService.findInsOrderByOrderId(orderId);
    }

    @Override
    public List<InsOrder> listInsOrderByOrderIds(List<Long> orderIds) {
        return insOrderService.listInsOrderByOrderIds(orderIds);
    }

    /**
     * 按条件查询参保师傅
     * @param insOrderMasterQuery
     * @return
     */
    @Override
    public List<InsOrderMaster> listInsOrderMasters(InsOrderMasterQuery insOrderMasterQuery) {
        return insOrderMasterService.listInsOrderMaster(insOrderMasterQuery);
    }

    /**
     * 更新参保订单 & 参保师傅
     * @param updateInsOrder
     * @param addInsOrderMasters
     * @param delInsOrderMasters
     */
    @Override
    @Transactional
    public void updateInsOrderAndMasters(InsOrder updateInsOrder,
                                         List<InsOrderMaster> addInsOrderMasters,
                                         List<InsOrderMaster> delInsOrderMasters) {
        // 更新参保订单信息
        insOrderService.updateInsOrderByKey(updateInsOrder);

        InsOrder dbInsOrder = insOrderService.findInsOrderByKey(updateInsOrder.getInsId());
        Date updateTime = updateInsOrder.getUpdateTime();

        // 新增参保师傅
        if (!CollectionUtils.isEmpty(addInsOrderMasters)) {
            for (InsOrderMaster item : addInsOrderMasters) {
                item.setStatus(GlobalConsts.YES);
                item.setCreateTime(updateTime);
                insOrderMasterService.insertInsOrderMaster(item);
            }
        }

        // 结束参保师傅
        if (!CollectionUtils.isEmpty(delInsOrderMasters)) {
            for (InsOrderMaster item : delInsOrderMasters) {
                item.setStatus(GlobalConsts.NO);
                item.setUpdateTime(updateTime);
                insOrderMasterService.updateInsOrderMasterByKey(item);
            }
        }

        { // 师傅保险备份
            List<InsOrderSync> insOrderSyncs = new LinkedList<>();

            // 新增参保师傅
            if (!CollectionUtils.isEmpty(addInsOrderMasters)) {
                for (InsOrderMaster item : addInsOrderMasters) {
                    InsOrderSync insOrderSync = buildInsOrderSync(dbInsOrder, item, updateTime);
                    insOrderSyncs.add(insOrderSync);
                }
            }

            // 结束参保师傅
            if (!CollectionUtils.isEmpty(delInsOrderMasters)) {
                for (InsOrderMaster item : delInsOrderMasters) {
                    InsOrderSync insOrderSync = buildInsOrderSync(dbInsOrder, item, updateTime);
                    insOrderSyncs.add(insOrderSync);
                }
            }

            if (!CollectionUtils.isEmpty(insOrderSyncs)) {
                insOrderSyncService.insertInsOrderSyncList(insOrderSyncs);
            }
        }

        // 保存师傅保险(太平洋保险)同步备份
        if (!CollectionUtils.isEmpty(addInsOrderMasters)) {
            for (InsOrderMaster item : addInsOrderMasters) {
                InsOrderMasterCpic masterCpic = buildInsOrderMasterCpic(dbInsOrder, item, dbInsOrder.getCreateTime());
                if (masterCpic != null) {
                    insOrderMasterCpicService.insert(masterCpic);
                }
            }
        }
    }

    /**
     * 结束按单保险订单
     * @param insOrder
     */
    @Override
    @Transactional
    public void endInsOrderAndMasters(InsOrder insOrder, List<InsOrderMaster> delInsOrderMasters,
                               InsOrderMasterSync insOrderMasterSync) {
        // 更新参保订单 & 参保师傅
        updateInsOrderAndMasters(insOrder, null, delInsOrderMasters );
        // 保存承担保险费用的师傅信息
        // 订单有可能没有承担保费的师傅（比如订单派单后又分单撤回至平台，然后又被取消），此时保费由公司承担
        if (insOrderMasterSync != null) {
            insOrderMasterSyncService.insertInsOrderMasterSync(insOrderMasterSync);
        }
    }

    /**
     * 保存参保订单 & 参保师傅
     * @param insOrder
     * @param insOrderMasters
     */
    @Override
    @Transactional
    public void saveInsOrder(InsOrder insOrder, List<InsOrderMaster> insOrderMasters) {
        insOrderService.insertInsOrder(insOrder);

        InsOrder dbInsOrder = insOrderService.findInsOrderByOrderId(insOrder.getOrderId());
        // 保存参保师傅
        for (InsOrderMaster item : insOrderMasters) {
            item.setInsId(dbInsOrder.getInsId());
            item.setStatus(GlobalConsts.YES);
            item.setCreateTime(dbInsOrder.getCreateTime());
            insOrderMasterService.insertInsOrderMaster(item);
        }

        // 保存师傅保险同步备份
        List<InsOrderSync> insOrderSyncs = new LinkedList<>();
        for (InsOrderMaster item : insOrderMasters) {
            insOrderSyncs.add(buildInsOrderSync(dbInsOrder, item, dbInsOrder.getCreateTime()));
        }
        insOrderSyncService.insertInsOrderSyncList(insOrderSyncs);

        // 保存师傅保险(太平洋保险)同步备份
        for (InsOrderMaster item : insOrderMasters) {
            InsOrderMasterCpic masterCpic = buildInsOrderMasterCpic(dbInsOrder, item, dbInsOrder.getCreateTime());
            if (masterCpic != null) {
                insOrderMasterCpicService.insert(masterCpic);
            }
        }
    }

    /**
     * 构造保险师傅同步对象
     * @param insOrder
     * @param insOrderMaster
     * @param createTime
     * @return
     */
    private InsOrderSync buildInsOrderSync(InsOrder insOrder, InsOrderMaster insOrderMaster, Date createTime) {
        InsOrderSync insOrderSync = new InsOrderSync();
        insOrderSync.setCode(String.valueOf(insOrder.getOrderId()));
        insOrderSync.setType(insOrder.getType());
        insOrderSync.setCityId(String.valueOf(insOrder.getNaturalCityId()));
        insOrderSync.setCityName(insOrder.getNaturalCityName());
        insOrderSync.setAddress(insOrder.getUserAddress());
        insOrderSync.setCategoryName(insOrder.getProductInfo());

        Integer status =
                Objects.equals(GlobalConsts.YES, insOrderMaster.getStatus())
                        ? INS_SYNC_STATUS_START : INS_SYNC_STATUS_END;
        insOrderSync.setStatus(status);
        insOrderSync.setPlatWork(insOrderMaster.getPlatWork());

        insOrderSync.setServicemanCardNo(insOrderMaster.getMasterCardNo());
        insOrderSync.setServicemanId(String.valueOf(insOrderMaster.getInsMasterId()));
        insOrderSync.setServicemanName(insOrderMaster.getMasterName());
        insOrderSync.setCreatedOn(createTime);
        insOrderSync.setTime(createTime);

        return insOrderSync;
    }

    /**
     * 构造保险师傅同步对象
     * @param insOrder
     * @param insOrderMaster
     * @param createTime
     * @return
     */
    private InsOrderMasterCpic buildInsOrderMasterCpic(InsOrder insOrder, InsOrderMaster insOrderMaster, Date createTime) {
        if (!checkMasterAge4Insure(insOrderMaster.getMasterCardNo())) {
            return null; // 年龄不满足买保险要求的不记
        }

        InsOrderMasterCpic cpicModel = new InsOrderMasterCpic();
        cpicModel.setInsId(insOrder.getInsId());
        cpicModel.setOrderId(insOrder.getOrderId());
        cpicModel.setMasterId(insOrderMaster.getMasterId());
        cpicModel.setMasterName(insOrderMaster.getMasterName());
        cpicModel.setMasterPhone(insOrderMaster.getMasterPhone());
        cpicModel.setMasterCardNo(insOrderMaster.getMasterCardNo());
        cpicModel.setSchemaCode(
                Objects.equals(InsConsts.PRICE_LV2, insOrder.getPriceLevel())
                        ? InsOrderMasterCpic.SCHEMA_CODE_FOUR
                        : InsOrderMasterCpic.SCHEMA_CODE_THIRD
        );
        cpicModel.setCreateTime(createTime);

        String insStartDate = DateUtil.toString(createTime, "yyyy-MM-dd 00:00:00");
        String insEndDate = DateUtil.toString(DateUtil.addDays(createTime, 30), "yyyy-MM-dd 00:00:00");
        cpicModel.setInsStartDate(insStartDate);
        cpicModel.setInsEndDate(insEndDate);

        cpicModel.setPlat(insOrder.getPlatWork());
        cpicModel.setCityId(insOrder.getCityId());
        cpicModel.setCompanyId(insOrder.getCompanyId());
        cpicModel.setCompanyName(insOrder.getCompanyName());
        cpicModel.setManageCompanyId(insOrder.getManageCompanyId());
        cpicModel.setManageCompanyName(insOrder.getManageCompanyName());
        cpicModel.setServCategId(insOrder.getServCategId());
        cpicModel.setCategOneId(insOrder.getCategOneId());
        cpicModel.setCategId(insOrder.getCategId());
        cpicModel.setProductId(insOrder.getProductId());
        cpicModel.setCategTag(insOrder.getCategTag());

        return cpicModel;
    }

    private boolean checkMasterAge4Insure(String masterCardNo) {
        if (!Pattern.matches(REG_CARDNO, masterCardNo)) {
            return true;    // 忽略身份证号无法识别的情况
        }

        /*
            买保险的年龄范围调整为男女都是16-65岁（包含16岁和65岁）2021.08.10 by lhl
        */
        long masterBirthTime = DateUtil.parse(masterCardNo.substring(6, 14), DateUtil.FORMAT_DATE2).getTime();
        //boolean isMale = (Integer.parseInt(masterCardNo.substring(16, 17)) % 2) == 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());

        calendar.add(Calendar.YEAR, -16);
        long latestBirthDate = calendar.getTimeInMillis();
        if (latestBirthDate < masterBirthTime) {
            return false;   // 不满16岁
        }

        //calendar.add(Calendar.YEAR, ((isMale ? -65 : -60) + 18));
        calendar.add(Calendar.YEAR, (-66 + 16));
        long earliestBirthDate = calendar.getTimeInMillis();
        if (earliestBirthDate > masterBirthTime) {
            return false;   // 超过65岁了
        }

        return true;
    }

}
